<template>
	<teleport to=".main" v-if="modalVisible && canRender">
		<div @click.stop ref="modalRef" class="CommonModal d-flex flex-column align-items-center bg-white">
			<div ref="dragRef" class="cursor-move title d-flex justify-content-center align-items-end">
				<div class="fs-5">{{ title }}</div>
				<CloseIcon @click="clickCancel" class="cursor-pointer" width="20px" height="20px" />
			</div>
			<div class="content" :style="contentStyle" :class="contentClass">
				<div class="main" :style="bodyStyle" :class="bodyClass">
					<slot name="default" />
				</div>
				<div class="position-absolute bottom-0 d-flex" :class="placementClass">
					<slot v-if="$slots.buttons" name="buttons" />
					<template v-else>
						<CustomButton v-if="cancelable" @click="clickCancel" class="me-2 px-4">
							<span class="px-4">
								{{ cancelText }}
							</span>
						</CustomButton>
						<CustomButton @click="$emit('confirm')" :theme="true">
							<span class="px-4">
								{{ okText }}
							</span>
						</CustomButton>
					</template>
				</div>
			</div>
		</div>
	</teleport>
</template>

<script lang="ts">
import { computed, defineComponent, onMounted, PropType, reactive, ref, toRefs, watch } from "vue";
import useDragMove from "@/hooks/useDragMove";
type Placement = "right" | "center" | "left";
export default defineComponent({
	emits: ["update:visible", "confirm", "cancel"],
	props: {
		visible: {
			type: Boolean,
			default: true,
		},
		title: {
			type: String,
			default: "",
		},
		okText: {
			type: String,
			default: "确定",
		},
		cancelText: {
			type: String,
			default: "取消",
		},
		bodyStyle: {
			type: String,
			default: "",
		},
		bodyClass: {
			type: String,
			default: "",
		},
		cancelable: {
			type: Boolean,
			default: false,
		},
		placement: {
			type: String as PropType<Placement>,
			default: "right",
		},
		contentStyle: {
			type: [String, Array, Object],
			default: "",
		},
		contentClass: {
			type: [String, Array, Object],
			default: "",
		},
	},
	setup(props, context) {
		const state = reactive({
			modalVisible: computed({
				get: () => props.visible,
				set: (newV) => context.emit("update:visible", newV),
			}),
			canRender: false,
			placementClass: computed(() => {
				if (props.placement === "left") {
					return "start-0";
				}
				if (props.placement === "center") {
					return "start-50 translate-x--50";
				}
				if (props.placement === "right") {
					return "end-0";
				}
			}),
		});
		const modalRef = ref(null);
		const dragRef = ref(null);
		onMounted(() => {
			state.canRender = true; //teleport标签必须检测到to指定的元素已经存在才能渲染
		});
		watch(
			() => state.modalVisible,
			(newV) => {
				if (newV) {
					useDragMove(modalRef, dragRef);
				}
			}
		);
		const clickCancel = () => {
			state.modalVisible = false;
			context.emit("cancel");
		};
		return {
			...toRefs(state),
			modalRef,
			dragRef,
			console,
			clickCancel,
		};
	},
});
</script>

<style scoped lang="scss">
.CommonModal {
	position: fixed;
	z-index: 999;
	top: 50vh;
	left: 50vw;
	transform: translate(-50%, -50%);
	width: 500px;
	min-height: 240px;
	background-color: #fff;
	border-radius: 6px;
	box-shadow: 0 0 2px 1.5px rgba($color: #000000, $alpha: 0.075);
	box-sizing: border-box;
	.title {
		font-weight: bold;
		width: 100%;
		height: 80px;
		padding-bottom: 22px;
		position: relative;
		> svg {
			position: absolute;
			top: 14px;
			right: 14px;
			filter: invert(0.5);
		}
	}
	.content {
		width: calc(100% - 36px * 2);
		flex: 1;
		position: relative;
		margin: 0 36px 26px;
		box-sizing: border-box;
		.main {
			min-height: 90px;
			margin-bottom: 46px;
		}
	}
}
</style>
